<template>
    <a-tree checkable show-line showIcon :tree-data="menus" :fieldNames="fieldNames" v-model:checkedKeys="permissions"
        default-expand-all style="height:400px;overflow-x:hidden;overflow-y:auto;" @check="treeCheck"/>
</template>

<script setup lang='tsx'>
import i18n from '@/i18n';
import { message } from 'ant-design-vue';
import { type Ref, ref, onMounted } from 'vue';
import { getPermissionsApi, givePermissionsApi } from '@/services/role';
import { MenuResultDto } from '@/models/menu';
import type { PermissionInputDto, RolePermissionDto } from '@/models/role-permissions';
import type { MenuRoleOutputDto } from '@/models/role';
import MenuIcon from "@/components/icon/index.vue";
import type { TreeProps } from 'ant-design-vue/lib/vc-tree';


const props = defineProps<{ id: number, code: string }>();
defineExpose({ ok });

const treeClickCount: Ref<number> = ref<number>(0);
const menus: Ref<Array<MenuResultDto>> = ref<Array<MenuResultDto>>(new Array<MenuResultDto>);
const permissions: Ref<Array<number>> = ref<Array<number>>(new Array<number>);
const fieldNames: TreeProps['fieldNames'] = {
    children: 'childrens',
    title: 'displayName',
    key: 'id'
};
const checkPermissionInputList: Ref<Array<MenuResultDto>> = ref<Array<MenuResultDto>>(new Array<MenuResultDto>);
const halfCheckedKeys: Ref<Array<number>> = ref<Array<number>>(new Array<number>);

onMounted(async () => {
    await permissionsGet();
})

async function permissionsGet(): Promise<void> {
    const response: MenuRoleOutputDto = await getPermissionsApi(props.code);
    menus.value = response.menuResultDtos;
    getPermissions(menus.value, response.rolePermissionDtos);
}

function getPermissions(items: Array<any>, rolePermissionDtos: Array<RolePermissionDto>): void {
    for (let i: number = 0; i < items.length; i++) {
        const item = items[i];
        item.icon = (
            <MenuIcon iconName={item.icon ? item.icon : "AlignRightOutlined"} />
        );
        if (item.childrens && item.childrens.length > 0) {
            getPermissions(item.childrens, rolePermissionDtos);
            continue;
        }
        for (let y: number = 0; y < rolePermissionDtos.length; y++) {
            const permissionCode =
                rolePermissionDtos[y].type == 1
                    ? item.code
                    : item.parentCode + item.code;
            if (rolePermissionDtos[y].permissionCode === permissionCode) {
                permissions.value.push(item.id);
            }
        }
    }
}

function treeCheck(checkedKeys: [], e: any): void {
    treeClickCount.value++;
    e.checkedNodes.forEach((checkedNode: MenuResultDto) => {
        const data = new MenuResultDto;
        data.code = checkedNode.code;
        data.displayName = checkedNode.displayName;
        data.id = checkedNode.id;
        data.parentCode = checkedNode.parentCode;
        data.type = checkedNode.type;
        data.sort = checkedNode.sort;
        checkPermissionInputList.value.push(data);
    });
    halfCheckedKeys.value = e.halfCheckedKeys;
}

function getCheckPermissionInputList(items: Array<MenuResultDto>): void {
    for (let i: number = 0; i < items.length; i++) {
        const index: number = halfCheckedKeys.value.indexOf(items[i].id);
        if (index !== -1) {
            const halfCheckedNode: MenuResultDto = items[i];
            const data: MenuResultDto = new MenuResultDto;
            data.code = halfCheckedNode.code;
            data.displayName = halfCheckedNode.displayName;
            data.id = halfCheckedNode.id;
            data.parentCode = halfCheckedNode.parentCode;
            data.type = halfCheckedNode.type;
            data.sort = halfCheckedNode.sort;
            checkPermissionInputList.value.push(data);
            halfCheckedKeys.value.splice(index, 1);
            if (halfCheckedKeys.value.length < 1) {
                return;
            }
        }
        const childrens: Array<MenuResultDto> | undefined = items[i].childrens;
        if (childrens && childrens.length > 0) {
            getCheckPermissionInputList(childrens);
        }
    }
}

async function ok(): Promise<boolean> {
    if (treeClickCount.value <= 0) {
        return true;
    }
    getCheckPermissionInputList(menus.value);
    const input: PermissionInputDto = {
        roleCode: props.code,
        menus: checkPermissionInputList.value
    };
    try {
        await givePermissionsApi(input);
        message.success(i18n.global.t("upperComputer.role.required.getSuccess"));
        return true;
    } catch (err) {
        return false;
    }
}
</script>